背景介绍

近期,我们监控到一起针对 BnbSmartChain 上的项目DCFToken的链上攻击事件,

https://bscscan.com/tx/0xa88b907960c3c5a9dfcfd28aff12136359034653e34fa6d7bb9a6ef9c7a0532f

被攻击的项目为 DCFToken ,攻击者通过此次攻击获利约为 8800 USD 。

攻击及事件分析

首先,攻击者创建了一个新的合约,然后调用了该合约,

零时科技 || DCFToken 攻击事件分析

接着,该合约从 PancakeSwapV3Pool 中利用 flash 贷了 2,750,000 BUSDT 。

零时科技 || DCFToken 攻击事件分析

随后,攻击者利用 flash 贷来的初始资金开始针对进行针对 DCFToken 的攻击。第一步,攻击者利用项目的未开源合约的兑换功能( BUSDT 兑换 DUSD )将该合约的所有 DUSD 使用 BUSDT 兑换,该函数的签名为 0xabb81c12 。

通过反编译我们得到该函数的具体实现如下:

零时科技 || DCFToken 攻击事件分析

第一步:

从代码中可以看出 BUSDT 和 DUSD 的兑换比例由 stor_5 控制,由于攻击时 stor_5 为 1000 ,所以BUSDT和 DUSD 兑换比例为 1:1 。因此,攻击者使用了 10,927 BUSDT 将该合约中的 DUSD 全部兑换。

零时科技 || DCFToken 攻击事件分析

第二步:

利用 DUSD 购买 DCFToken ,该函数的签名为 0x62ee2f14 。通过反编译我们可以看到具体的实现如下:

零时科技 || DCFToken 攻击事件分析

简单来说,该函数实现了使用 DUSD 购买 DCFToken 的功能,其中购买价格由 PancakeSwapV2 的BUSDT 和 DCFToken 的价格决定。也就意味着在该函数的逻辑中, DUSD 和 BUSDT 的价格为 1:1 。

接着,会将购买的 DCFToken 的 1% 转入系统地址中。

攻击者随后利用第一步中购买的所有 DUSD 购买 DCFToken 。

零时科技 || DCFToken 攻击事件分析

接着,攻击者重复上述的步骤,直到将项目方用于兑换 DUSD 和 DCFToken 的合约中的 DCF 买空。随后,攻击者利用 PancakeSwapV2 的兑换功能,将手中的 DCFToken 兑换为 BUSDT ,来操纵DCFToken 的价格,经过此次兑换,DCFToken 的价格由 1 BUSDT = 126 DCFToken 拉升到了 1BUSDT = 3 DCFToken 。

兑换前:

零时科技 || DCFToken 攻击事件分析

兑换后:

零时科技 || DCFToken 攻击事件分析

第三步:

攻击者再掏空项目方合约中的 DCFToken 后,使用该合约的 DCFToken 兑换 DUSD ,该函数的签名为 0xd5088d27 ,与第二步中使用 DUSD 购买 DCFToken 类似。同样的,购买价格由PancakeSwapV2 的 BUSDT 和 DCFToken 的价格决定。也就意味着在该函数的逻辑中,DUSD 和BUSDT 的价格为 1:1 。接着,会将购买的 DUSD 的 1% 转入系统地址中。

零时科技 || DCFToken 攻击事件分析

第四步:

攻击者再利用项目方合约中的 DUSD 兑换 BUSDT 的功能,该函数的签名为 0xfea1cdc9 ,兑换比例为 1:1 ,但是 1% 的 BUSDT 会转入项目方地址中。

零时科技 || DCFToken 攻击事件分析

攻击者继续重复第三和第四步,直到掏空项目方合约中的 BUSDT 。

最后,攻击者使用剩余的 DCFToken ,利用 PancakeSwapV2 全部兑换为了 BUSDT ,再归还 flash 的贷款和利息后,获利 8,763 BUSDT 。

简单来讲,该项目的漏洞出现在兑换的价格计算上。DCFToken 的价格依赖于 PancakeSwap ,但是,使用项目方合约兑换又不影响 DCFToken 的价格。因此攻击者先使用 BUSDT 兑换 DUSD 再兑换DCF(99%) 掏空 DCFToken ,再利用 PancakeSwap 的 swap 拉升 DCFToken 的价格,最后使用DCFToken 兑换 DUSD(99%) 再兑换 BUSDT(99%) 来完成获利。

总结

本次漏洞成因主要是因为 DCFToken 项目方合约在获取 DCFToken 的价格时,通过单一来源PancakeSwapV2 来计算,导致价格被攻击者操纵,最终利用价差套利。建议项目方在设计经济模型、价格计算机制和代码运行逻辑时要多方验证,合约上线前审计时尽量选择多个审计公司交叉审计。